/*
 *  FileName BitmapSource.cpp
*/

#include "stdafx.h"

#include "BitmapSource.h"

namespace DeepZoomImage
{
	BitmapSource::BitmapSource ()
	{
		image_surface = NULL;
		data = NULL;
		own_data = true;
		m_PixelWidth = 0;
		m_PixelHeight = 0;
		imageStride = 0;
	}

	BitmapSource::~BitmapSource ()
	{
		if (image_surface) {
			cairo_surface_destroy (image_surface);
			image_surface = NULL;
		}

		if (data && own_data) {
			g_free (data);
			data = NULL;
		}

	}

	gpointer BitmapSource::GetBitmapData ()
	{
		return data;
	}

	void BitmapSource::OnIsAttachedChanged (bool value)
	{
		//ImageSource::OnIsAttachedChanged (value);

		if (value) {
			if (image_surface == NULL) {
				// #246 requires this - it detaches and then reattaches
				// glyphs, and without this they don't show up again.
				Invalidate ();
			}
		}
	}

	void BitmapSource::SetBitmapData (gpointer data, bool own_data)
	{
		if (data == NULL) {
			SetPixelWidth (0.0);
			SetPixelHeight (0.0);
		}

		if (this->data && this->own_data)
			g_free (this->data);
		this->own_data = own_data;
		this->data = data;
	}

	void BitmapSource::Invalidate ()
	{
		if (GetPixelWidth () == 0 || GetPixelHeight () == 0)
			return;

		if (image_surface) {
			cairo_surface_destroy (image_surface);
			image_surface = NULL;
		}

		image_surface = cairo_image_surface_create_for_data ((unsigned char *) GetBitmapData (), CAIRO_FORMAT_ARGB32, 
 			GetPixelWidth (), GetPixelHeight (), GetPixelWidth () * 4);

// 		image_surface = cairo_image_surface_create_for_data ((unsigned char *) GetBitmapData (), CAIRO_FORMAT_RGB24, 
// 			GetPixelWidth (), GetPixelHeight (), GetPixelWidth () * 3);

		//cache.Release ();
		//Emit (BitmapSource::PixelDataChangedEvent);
	}

	MoonSurface* BitmapSource::GetSurface (Context *ctx)
	{
		MoonSurface *surface;

		surface = ctx->Lookup (&cache);
		if (surface)
			return surface;

		ctx->Push (Context::Group (Rect (0, 0, GetPixelWidth (), GetPixelHeight ())));
		ctx->Blit ((unsigned char *) GetBitmapData (), GetPixelWidth () * 4);
		ctx->Pop (&surface);
		ctx->Replace (&cache, surface);
		surface->unref ();

		return ctx->Lookup (&cache);
	}

	gint32 BitmapSource::GetPixelWidth ()
	{
		return m_PixelWidth;
	}

    gint32 BitmapSource::GetPixelHeight ()
	{
		return m_PixelHeight;
	}

	void BitmapSource::SetPixelWidth (gint32 width)
	{
		m_PixelWidth = width;
	}

	void BitmapSource::SetPixelHeight (gint32 height)
	{
		m_PixelHeight = height;
	}
}

